package com.henry.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.henry.feign.service.FeignStuService;
import com.henry.pojo.Stu;
import com.henry.sentinel.block.DemoBlockHandler;
import com.henry.sentinel.fallback.DemoFallBack;
import com.henry.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @program: spring-cloud-alibaba-demo
 * @description:
 * @author: Henry.zhang
 * @create: 2022-08-30 15:00
 */
@RestController
@RequestMapping("demo")
@Slf4j
public class DemoController {

    @Autowired
    private FeignStuService feignStuService;

    @SentinelResource(
            value = "getOne",
            blockHandler = "foo1",
            //告诉sentinel，如果出现限流、熔断等情况需要使用备用方法，就去DemoBlockHandler中找，方法名和当前方法一致的方法
            blockHandlerClass = DemoBlockHandler.class
//            fallback = "foo1",
//            //告诉sentinel，出现业务异常后，去DemoFallBack中找降级方法
//            fallbackClass = DemoFallBack.class
    )
    @RequestMapping("getOne")
    public R getOne(@RequestParam("id") int id){
        return feignStuService.getOne(id);
    }


    @SentinelResource(
            value = "getAll",
            blockHandler = "foo1",
            //告诉sentinel，如果出现限流、熔断等情况需要使用备用方法，就去DemoBlockHandler中找，方法名和当前方法一致的方法
            blockHandlerClass = DemoBlockHandler.class
//            fallback = "foo1",
//            //告诉sentinel，出现业务异常后，去DemoFallBack中找降级方法
//            fallbackClass = DemoFallBack.class
    )
    @RequestMapping("getAll")
    public R getAll(){
        return feignStuService.getAll();
    }



    @SentinelResource(
            value = "foo",
            blockHandler = "foo",
            //告诉sentinel，如果出现限流、熔断等情况需要使用备用方法，就去DemoBlockHandler中找，方法名和当前方法一致的方法
            blockHandlerClass = DemoBlockHandler.class
//            fallback = "foo1",
//            //告诉sentinel，出现业务异常后，去DemoFallBack中找降级方法
//            fallbackClass = DemoFallBack.class
    )
    @RequestMapping("foo")
    public R foo(@RequestParam("id") Integer id) throws Exception{
        return feignStuService.foo(id);
    }



    /**
     * blockHandler: 专用于处理sentinel流控、熔断、热点数据访问限制后，使用备用方法；不处理业务异常
     * fallback:用来处理业务异常后的降级方法
     * @param i
     * @return
     * @throws Exception
     */
    @SentinelResource(
            value = "f1",
            blockHandler = "foo1",
            //告诉sentinel，如果出现限流、熔断等情况需要使用备用方法，就去DemoBlockHandler中找，方法名和当前方法一致的方法
            blockHandlerClass = DemoBlockHandler.class,
            fallback = "foo1",
            //告诉sentinel，出现业务异常后，去DemoFallBack中找降级方法
            fallbackClass = DemoFallBack.class)
    @RequestMapping("f1")
    public R foo1(@RequestParam("i") int i) throws Exception {

        if(i % 2 == 0){
            throw new Exception("随机异常");
        }

//        if(i % 2 == 0){
//            Thread.sleep(400);
//        }

        System.out.println("haha");
        return R.ok("hehe");
    }

//    /**
//     * 做为某个方法被sentinel限流后使用的备用方法，必须在参数列表上接收 异常对象 BlockException e
//     * @param e
//     * @return
//     */
//    public R foo1BlockHandler(@RequestParam("i") int i,BlockException e){
//        log.info("出现的异常：",e); //埋点
//        return new R(444,"访问过于频繁，请稍后重试！",i);
//    }
//
//    public R foo1Fallback(@RequestParam("i") int i,Throwable e){
//        log.info("出现的异常：",e); //埋点
//        return new R(555,"出错啦~！",i);
//    }



    @RequestMapping("f2")
    public R foo2(){
        System.out.println("haha");
        return R.ok("hehe");
    }


    @GetMapping("getAllList")
    public List<Stu> getAllList(){

        List<Stu> list = feignStuService.getAllList();

//        try {
//            Thread.sleep(8000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        return list;
    }


}
